package com.ruoyi.labdata.service.impl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.labdata.domain.LabFlowInstance;
import com.ruoyi.labdata.domain.LabFlowTask;
import com.ruoyi.labdata.mapper.LabFlowTaskMapper;
import com.ruoyi.labdata.service.ILabFlowInstanceService;
import com.ruoyi.labdata.service.ILabFlowTaskService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.utils.LockUtil;

/**
 * 流程任务Service业务层处理
 * 
 * @author winner pan
 * @date 2022-03-10
 */
@Service
public class LabFlowTaskServiceImpl implements ILabFlowTaskService {
	@Autowired
	private LabFlowTaskMapper labFlowTaskMapper;

	@Autowired
	private ILabFlowInstanceService labFlowInstanceService;
	@Autowired
	private ISysRoleService sysRoleService;
	@Autowired
	private LockUtil lockUtil;
	@Autowired
	private EndTaskListenerFactory  endTaskListenerFactory;
	
	private static final String  lockkey = "TASK";
	/**
	 * 查询流程任务
	 * 
	 * @param taskId
	 *            流程任务ID
	 * @return 流程任务
	 */
	@Override
	public LabFlowTask selectLabFlowTaskById(Long taskId) {
		return labFlowTaskMapper.selectLabFlowTaskById(taskId);
	}

	/**
	 * 查询流程任务列表
	 * 
	 * @param labFlowTask
	 *            流程任务
	 * @return 流程任务
	 */
	@Override
	public List<LabFlowTask> selectLabFlowTaskList(LabFlowTask labFlowTask) {
		return labFlowTaskMapper.selectLabFlowTaskList(labFlowTask);
	}

	/**
	 * 新增流程任务
	 * 
	 * @param labFlowTask
	 *            流程任务
	 * @return 结果
	 */
	@Override
	public int insertLabFlowTask(LabFlowTask labFlowTask) {
		return labFlowTaskMapper.insertLabFlowTask(labFlowTask);
	}

	/**
	 * 修改流程任务
	 * 
	 * @param labFlowTask
	 *            流程任务
	 * @return 结果
	 */
	@Override
	public int updateLabFlowTask(LabFlowTask labFlowTask) {
		return labFlowTaskMapper.updateLabFlowTask(labFlowTask);
	}
	/***
	 * 节点提交.
	 * @param labFlowTask
	 * @return
	 */
	@Override
	@Transactional
	public int completedTask(LabFlowTask labFlowTask){
		LabFlowTask updateTask = new LabFlowTask();
		if(labFlowTask.getTaskId()==null){
			throw new RuntimeException("节点ID：taskId 为空!");
		}
		updateTask.setTaskId(labFlowTask.getTaskId());
		if(labFlowTask.getFinishFlagOpt()==null){
			throw new RuntimeException("审批结果：finishFlagOpt 为空!");
		}
		LabFlowTask queryTask = this.selectLabFlowTaskById(labFlowTask.getTaskId());
		if(queryTask.getOperation().indexOf(labFlowTask.getFinishFlagOpt())<0){
			throw new RuntimeException("当前审批操作为:"+labFlowTask.getFinishFlagOpt()+",但该节点可操作的范围值为:"+queryTask.getOperation());
		}
		checkPermitTask(queryTask, false);
		updateTask.setFinishFlagOpt(labFlowTask.getFinishFlagOpt());
		updateTask.setTaskStatusOpt("completed");
		updateTask.setFinishComments(labFlowTask.getFinishComments());
		updateTask.setFinishTime(new Date());
		updateTask.setIsCurrentOpt(0);
		this.updateLabFlowTask(updateTask);
		
		if(!labFlowTask.getFinishFlagOpt().equals("refused")){
			doNextTask(labFlowTask);
		}else{
			/*LabFlowTask lastTask = this.getLastTask(labFlowTask);
			if(lastTask==null){
				throw new RuntimeException("当前节点ID:"+labFlowTask.getTaskId()+", 序号:"+labFlowTask.getNodeNo()+"已经不能获取到上一个节点.");
			}
			if( lastTask.isStartNode()){
				LabFlowInstance labFlowInstance = new LabFlowInstance();
				labFlowInstance.setInstanceId(labFlowTask.getInstanceId());
				labFlowInstance.setFlowStatusOpt("uncommitted");
				labFlowInstanceService.updateLabFlowInstance(labFlowInstance);
			}
			//插入两条数据
			List<LabFlowTask> allTaskList =  this.selectLabFlowTaskByInstanceId(labFlowTask.getInstanceId());
			
			//当前节点所在位置,node no 从1开始计算
			Integer index = labFlowTask.getNodeNo().intValue();
			LabFlowTask toDoLastLastTask = new LabFlowTask();
			copyTask(toDoLastLastTask, lastTask);
			toDoLastLastTask.setNodeNo(index+1);
			toDoLastLastTask.setIsCurrentOpt(1);
			LabFlowTask toDoCurrentTask = new LabFlowTask();
			LabFlowTask currentTask = allTaskList.get(index);
			copyTask(toDoCurrentTask, currentTask);
			toDoCurrentTask.setNodeNo(index+2);
			this.insertLabFlowTask(toDoLastLastTask);
			this.insertLabFlowTask(toDoCurrentTask);
			for(int i=index;i<allTaskList.size();i++){
				LabFlowTask item = allTaskList.get(i); 
				item.setNodeNo(item.getNodeNo()+2);
				this.updateLabFlowTask(item);
			}*/
			if(labFlowTask.getInstanceId()==null){
				LabFlowTask task = this.selectLabFlowTaskById(labFlowTask.getTaskId()); 
				labFlowTask.setInstanceId(task.getInstanceId());
			}
			LabFlowTask endTask = this.labFlowTaskMapper.selectLabFlowTaskEnd(labFlowTask.getInstanceId());
			this.endFlow(endTask,"refused");
		}
		return 1;
	}

	private void doNextTask(LabFlowTask labFlowTask) {
		LabFlowTask nextTask = this.getNextTask(labFlowTask);
		if(nextTask!=null){
			if(nextTask.isEndNode()){
				endFlow(nextTask, "finished");
			}else{	
				//自动通过
				if(nextTask.getApprovalTypeOpt().equals("1")){
					nextTask.setSignUser("系统");
					nextTask.setSignTime(new Date());
					nextTask.setFinishFlagOpt("passed");
					nextTask.setTaskStatusOpt("completed");
					nextTask.setFinishComments("抄送节点无需审核");
					nextTask.setFinishTime(nextTask.getSignTime());
					this.updateLabFlowTask(nextTask);
					this.doNextTask(nextTask);
				}else{
					nextTask.setIsCurrentOpt(1);
				}
			}
			this.updateLabFlowTask(nextTask);
		}
	}

	private void endFlow(LabFlowTask endTask, String flowStatus) {
		endTask.setFinishFlagOpt("end");
		endTask.setSignTime(new Date());
		endTask.setFinishTime(endTask.getSignTime());
		endTask.setTaskStatusOpt("completed");
		endTask.setIsCurrentOpt(1);
		endTask.setSignUser("系统");
		//更新完成流程
		LabFlowInstance labFlowInstance = new LabFlowInstance();
		labFlowInstance.setInstanceId(endTask.getInstanceId());
		labFlowInstance.setFlowStatusOpt(flowStatus);//finished
		labFlowInstance.setEndTime(endTask.getSignTime());
		labFlowInstanceService.finishLabFlowInstance(labFlowInstance);
		endTaskListenerFactory.executeTask(endTask.getInstanceId());
		
	}

	/*private void copyTask(LabFlowTask toDoTask, LabFlowTask task) {
		toDoTask.setInstanceId(task.getInstanceId());
		toDoTask.setNodeId(task.getNodeId());
		toDoTask.setNodeRoles(task.getNodeRoles());
		toDoTask.setTaskStatusOpt("unsigned");
	}*/
	
	/**
	 * 节点签名.
	 * @param labFlowTask
	 * @return
	 */
	@Override
	public int signedTask(Long taskId){
		LabFlowTask queryTask = this.selectLabFlowTaskById(taskId);
		checkPermitTask(queryTask, true);
		LabFlowTask signTask = new  LabFlowTask();
		signTask.setTaskId(taskId);
		signTask.setSignTime(new Date());
		signTask.setSignUser(SecurityUtils.getLoginUser().getUser().getUserName());
		boolean getLock = lockUtil.lock(getLockKey(taskId), 1000*10);
		if(!getLock){
			throw new RuntimeException("系统忙请稍后操作.");
		}
		return this.labFlowTaskMapper.signLabFlowTask(signTask);
	}

	private String getLockKey(Long taskId) {
		return lockkey+taskId;
	}
	
	private void checkPermitTask(LabFlowTask labFlowTask, boolean isSign){
		SysUser loginUser = SecurityUtils.getLoginUser().getUser();
		if(!isSign){
			if(!labFlowTask.getSignUser().equals(loginUser.getUserName())){
				throw new RuntimeException("当前用户不是签收人员，没有任务:"+labFlowTask.getNodeName()+" 的操作权限.");
			}
			return ;
		}
		//List<Integer> roleIds = sysRoleService.selectRoleListByUserId(loginUser.getUserId());
		boolean ispermit = isHasPermit(labFlowTask.getNodeUsers(),loginUser.getUserId());
		if(!ispermit){
			throw new RuntimeException("当前用户没有流程任务:"+labFlowTask.getNodeName()+" 的操作权限.");
		}
	}
	private boolean isHasPermit(String taskRoleIds, Long userId){
		String[] taskRoleTdArr = taskRoleIds.split(",");
		for(String item : taskRoleTdArr){
			if(Long.valueOf(item) == userId.longValue()){
				return true;
			}
		}
		return false;
	}

	/**
	 * 批量删除流程任务
	 * 
	 * @param taskIds
	 *            需要删除的流程任务ID
	 * @return 结果
	 */
	@Override
	public int deleteLabFlowTaskByIds(Long[] taskIds) {
		return labFlowTaskMapper.deleteLabFlowTaskByIds(taskIds);
	}
	

	/**
	 * 删除流程任务信息
	 * 
	 * @param taskId
	 *            流程任务ID
	 * @return 结果
	 */
	@Override
	public int deleteLabFlowTaskById(Long taskId) {
		return labFlowTaskMapper.deleteLabFlowTaskById(taskId);
	}
	
	public List<LabFlowTask> selectLabFlowTaskByInstanceId(Long instanceId){
		return labFlowTaskMapper.selectLabFlowTaskByInstanceId(instanceId);
	}
	
	/**
	 * 获取下一个节点.
	 * @param currentNode
	 * @return
	 */
	@Override
	public LabFlowTask getNextTask(LabFlowTask currentTask){
		if(currentTask.getTaskId()==null){
			throw new RuntimeException("任务ID: taskId为空.");
		}
		if(currentTask.getInstanceId()==null || currentTask.getNodeNo()==null){
			LabFlowTask queryTask = this.selectLabFlowTaskById(currentTask.getTaskId());
			currentTask.setInstanceId(queryTask.getInstanceId());
			currentTask.setNodeNo(queryTask.getNodeNo());
			currentTask.setNodeUsers(queryTask.getNodeUsers());
		}
		List<LabFlowTask> taskList = this.selectLabFlowTaskByInstanceId(currentTask.getInstanceId());
		if(currentTask.getNodeNo()<taskList.size()){
			LabFlowTask nextTask= taskList.get(currentTask.getNodeNo().intValue());
			if(nextTask.getNodeNo()==taskList.size()){
				nextTask.setEndNode(true);
			}
			return nextTask;
		}
		return null;
	}
	/**
	 * 获取上一个节点.
	 * @param currentNode
	 * @return
	 */
	@Override
	public LabFlowTask getLastTask(LabFlowTask currentTask){
		if(currentTask.getTaskId()==null){
			throw new RuntimeException("任务ID: taskId为空.");
		}
		if(currentTask.getInstanceId()==null || currentTask.getNodeNo()==null){
			LabFlowTask queryTask = this.selectLabFlowTaskById(currentTask.getTaskId());
			currentTask.setInstanceId(queryTask.getInstanceId());
			currentTask.setNodeNo(queryTask.getNodeNo());
			currentTask.setNodeUsers(queryTask.getNodeUsers());
		}
		if(currentTask.getNodeNo()==1){
			return null;
		}
		List<LabFlowTask> taskList = this.selectLabFlowTaskByInstanceId(currentTask.getInstanceId());
		if(currentTask.getNodeNo()-2 >=0){
			LabFlowTask lastTask = taskList.get(currentTask.getNodeNo().intValue() - 2);
			if(lastTask.getNodeNo() ==1){
				lastTask.setStartNode(true);
			}
			return lastTask;
		}
		return null;
	}
	/**
	 * 需要在控制器增加一个同步锁LockUtil.
	 * @param taskId
	 * @return
	 */
	@Override
	public int resetTask(Long taskId){
		LabFlowTask task = this.selectLabFlowTaskById(taskId);
		checkPermitTask(task, false);
		return labFlowTaskMapper.resetLabFlowTask(taskId);
	}
	@Override
	@Transactional
	public int withDraw(Long taskId){
		LabFlowTask task = this.selectLabFlowTaskById(taskId);
		checkPermitTask(task, false);
		LabFlowTask queryTask = new LabFlowTask();
		queryTask.setInstanceId(task.getInstanceId());
		queryTask.setNodeNo(task.getNodeNo()+1);
		LabFlowTask currentTask = labFlowTaskMapper.selectLabFlowTaskByInstanceIdAndNo(queryTask);
		String lockey = getLockKey(currentTask.getTaskId());
		boolean getLock = lockUtil.lock(lockey, 1000*60);
		if(!getLock){
			throw new RuntimeException("系统忙请稍后操作.");
		}
		if(currentTask.getSignUser()!=null){
			lockUtil.unLock(lockey);
			throw new RuntimeException("已经被签收，不能撤回!");
		}
		if(task.getNodeNo()==1){//初始节点
			this.labFlowInstanceService.withDrawLabFlowInstance(task.getInstanceId());
			this.labFlowTaskMapper.deleteLabFlowTaskByInstanceId(task.getInstanceId());
		}else{
			this.labFlowTaskMapper.withDrawLabFlowTask(taskId);
			currentTask.setIsCurrentOpt(0);
			this.labFlowTaskMapper.updateLabFlowTask(currentTask);
		}
		lockUtil.unLock(lockey);
		return 1;
	}
	@Override
	 public List<LabFlowTask> selectTodoTaskList(LabFlowTask labFlowTask){
		 return this.labFlowTaskMapper.selectTodoTaskList(labFlowTask);
	 }
	@Override
	 public List<LabFlowTask> selectDoneTaskList(LabFlowTask labFlowTask){
		 return this.labFlowTaskMapper.selectDoneTaskList(labFlowTask);
	 }
	
	public LabFlowTask checkUserTaskPermit(LabFlowTask labFlowTask){
		return this.labFlowTaskMapper.checkUserTaskPermit(labFlowTask);
	}
}
